TCP 数据段格式

传输层建立【端口 -> 端口】之间的通信,网络层建立【主机 -> 主机】之间的通信。
TCP 数据段

  • 序列号TCP把连接中发送到所有数据,按字节进行编号。当 SYN=1 时,序列号seq就是报文段中第一个字节的数据编号。
  • 确认号:是当前报文段的最后一个字节编号+1,也就是下一个报文段的序列号。确认号表示,已接受小于该确认号的所有数据。
  • 窗口: 窗口大小是TCP接受缓冲区的剩余大小,用来进行流量控制。发送方不能够发送超过对方窗口大小的数据,否则会被丢掉。

TCP 与 UDP 区别

  • TCP是面向连接的;而UDP是不需要建立连接,即发送数据之前不需要建立连接。
  • TCP是可靠的,它保证数据的正确性;而UDP是不可靠的,可能会丢包。
  • UDP的实时性强,工作效率比TCP高,适用于高速传输和实时性要求比较高的通信或者广播通信。
  • TCP是点对点连接;UDP支持多对多的交互通信。
  • TCP对系统资源要求较高;UDP对系统资源要求较少。

TCP 为什么是可靠连接?

TCP都有一个发送缓冲区和一个接受缓冲区。

  • TCP数据段里的序列号 Seq 能使TCP保证按序到达
  • TCP数据段里的确认号 Ack 能使TCP保证不丢包,超时了会重传。
  • TCP拥有 流量控制 机制,TCP数据段里还有一个2个字节的窗口字段,它表示 接受缓冲区 里的剩余空间,发送方 根据这个窗口里的大小,发送比窗口小的数据量,否则发送的数据会被丢掉。这几点让TCP能够保证可靠连接。
  • TCP拥有 拥塞控制 机制。

UDP 为什么是不可靠的?

UDP没有发送缓冲区,只有一个接受缓冲区。所以只要有数据就会发送,不管对方能不能接受。当对方的接受缓冲区满了之后,新来的数据就会被丢掉,UDP是没有流量控制的,也没有确认号,所以UDP是不可靠的。

TCP 三次握手

TCP 三次握手

  • 第一次握手:客户端将标识位 SYN 设置为 1,并且随机产生一个值 x,令seq = x,把报文段发送给服务端。
  • 第二次握手:服务端看到 SYN = 1 就知道它是要请求建立连接,服务端把 SYNACK 都设置为 1,并且令ack = x + 1,随机生成一个值 y,令seq = y,告诉对方它的序列号。
  • 第三次握手:客服端收到数据段后检查 ACK 是否为 1,ack == x + 1?如果是,就把标志位 ACK 设置为 1,令ack = y + 1,并且发送给服务端,服务端也做同样的判断后,如果正确,就说明连接建立成功。客户端与服务端之间可以开始传输数据了。

TCP 四次挥手

TCP 四次挥手

  • 第一次挥手:客户端将标志位 FIN 设置为 1,用来断开与服务端的数据传输。
  • 第二次挥手:服务端收到对方的关闭连接请求之后,发送一个确认号,确认号 ack 等于对方的序列号 seq + 1.
  • 第三次挥手:同上。
  • 第四次挥手:同上。

为什么建立连接是三次握手,而关闭连接是四次挥手?

因为三次握手时,可以把标志位 SYNACK 放在同一个报文段发送。
但关闭连接时,当收到对方的 FIN 通知时,它仅仅表示着对方已经没有数据发送了,但可能,我还有没把全部数据发送给对方。所以不能立马把 socket 连接关闭掉,等我把数据全部发送完之后,再发送 FIN 通知,如果收到对方的确认号了,就说明双方的连接都关闭了。所以在大多数情况下,FINACK 报文段是分开发送的。

为什么不能用两次握手进行连接?

因为 两次握手 只能得到一方的确认,而TCP连接就是为了,让双方彼此知道对方可以正确地接受数据了,并且协商双方的初始序列号。所以TCP连接一定需要 三次握手,不能 两次握手

为什么 TIME_WAIT 状态需要经过 2MSL 才能进入 CLOSED 状态?

因为在第四次挥手时发送的 ACK 报文段可能在传输过程中丢失,如果服务端没有收到 ACK 就会重新发送 FIN 报文段。所以客户端至少要等一次发送和一次回复所需要的最大时间,也就是 2MSL.

MSL (Maximum Segment Lifetime):报文段在网络中的最长生存时间。